23.05.17
오늘 한 일
- 알고리즘 문제 풀이
- 블로그 정리
- 포트폴리오 정리
- 학교 멘토링
- 익스텐션 개발
- background script 활용하여 스토리지에 데이터 넣기
- 동영상 과제 크롤링 제대로 되지 않는 오류 해결
- 함수형 프로그래밍 스터디 진행
익스텐션 개발
background script 활용하기
chrome.storage.local.set()
을 사용하여 스토리지에 과제 데이터를 넣어주었다.
/*
* 스토리지에 데이터 저장
* updateAt: 데이터를 업데이트한 시간
* courses: 강의 리스트
* activities: 과제 리스트(동영상, 과제)
*/
const updateAt = new Date().getTime();
chrome.storage.local.set({
updateAt,
courses,
activities,
});
/*
* 스토리지에 저장된 데이터 가져오기
* 스토리지에 데이터가 있으면 가져와서 state에 넣어준다.
* 스토리지에 데이터가 없으면 refresh 진행
* 스토리지에 저장된 데이터가 REFRESH_TIME보다 지났으면 refresh 진행
*/
chrome.storage.local.get(
['updateAt', 'courses', 'activities'],
({ updateAt, courses, activities }) => {
if (!updateAt || !courses || !activities) return setIsRefresh(true);
const diff = new Date().getTime() - updateAt;
const isOverRefreshTime = diff > REFRESH_TIME;
if (!isOverRefreshTime) {
setCourseList([{ id: '-1', title: '전체' }, ...courses]);
setActivityList(activities);
setIsRefresh(false);
} else {
setIsRefresh(true);
}
}
);
추가로, 사용자가 최초 설치 시에 기존에 사이버캠퍼스에 접속해있다면 바로 content script를 주입시키도록 구현했다.
원래는 이 방법을 생각하지 않았었는데, 프론트 오픈채팅방에서 어떤 분이 이걸 구현하려고 하는데 잘 안된다고 하셔서 같이 고민해보면서 해결하게 되었다. 그리고 나도 적용해보았다.
chrome.runtime.onInstalled.addListener(async () => {
for (const cs of chrome.runtime.getManifest().content_scripts) {
for (const tab of await chrome.tabs.query({ url: cs.matches })) {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: cs.js,
});
cs.css?.forEach(css => {
chrome.scripting.insertCSS({
target: { tabId: tab.id },
files: [css],
});
});
}
}
});
위 방법을 사용하려면 권한이 필요하다. manifest.json
에 아래와 같이 추가해주면 된다. storage
는 아까 데이터 저장하기 위해 사용한 권한이라 위 방법만 할거면 필요없다.
{
"host_permissions": ["https://cyber.gachon.ac.kr/*"],
"permissions": ["storage", "scripting", "activeTab"]
}
동영상 과제 크롤링 제대로 되지 않는 오류 해결
오늘 23학번 후배와 멘토링을 진행했다. 1시간 정도 파이썬 과목에서 배운 내용 중에 모르는 부분을 알려주었다. 끝나고 가기 전에 내가 만든 익스텐션을 홍보할 겸 그 친구의 아이디로 들어가서 익스텐션을 켰다. 근데 정상적으로 작동하지 않고 콘솔에 에러가 많이 떠서 당황했다.
개발하면서 테스트는 내 계정으로만 했었는데 난 듣는 과목 수도 적고 과제도 별로 없어서 이런 오류가 나지 않았었다. 특히 동영상 과제도 많이 없어서 오류를 인지하지 못했던 것 같다.
오류 내용은 getLinkId
라는 유틸 함수에서 link
를 인자로 받아오는데, link가 undefined라 substring
메서드를 사용할 수 없어서 난 에러였다. 그것 때문에 연쇄적으로 에러가 떠버렸다.
그래서 오늘 멘토링이 끝나고 집 가자마자 원인을 찾아서 수정했다.
getLinkId
를 사용하는 곳은 세 곳이다.
getCourses
함수에서 강의 link의 id를 가져올 때getAssignments
함수에서 과제 link의 id를 가져올 때getVideoAtCourseDocument
함수에서 동영상 link의 id를 가져올 때
link는 a태그의 href 속성에서 가져왔었다. 근데 로그를 찍어보니 undefined가 나오는 경우도 있었다.
나는 여기서 예외처리를 어디서 해야할 지 고민이 들었다.
getLinkId
에서 예외처리를 해주기getCourses
,getAssignments
,getVideoAtCourseDocument
에서 예외처리를 해주기
타입스크립트에서 인자값의 타입을 명시해주어도 런타임에서는 undefined가 들어올 수 있다. 내가 생각했을 때는 1번의 방법을 사용하고, 만약 타입이 다른 게 들어오면 에러를 던져주는 방법을 사용하면 좋을 것 같았다.
하지만 일단 당장 수정해야했기 때문에 임시로 2번의 방법을 사용했다.
getLinkId
가 실행되기 전에 인자 값의 타입을 확인하고 타입이 다르면 return해줘서 다음 과제를 가져오도록 했다.
근본적인 원인이 있었다. 애초에 동영상 과제를 크롤링할 때 잘못 파싱해서 이상한 값들이 저장되고 있었다. 이로 인해 과제 제출 여부도 제대로 나오지 않고 있었고 동영상 과제도 제대로 나오지 않았던 것이다.
전부 수정해서 1.0.5
버전을 배포했다.
깨달은 점
배포를 했고, 이미 사용하고 있는 사람이 있는데 크리티컬한 오류가 있어서 당황했다. 이래서 QA가 중요하고 테스트코드를 짜야하는구나..
예외 처리를 잘 안해놔서 오류가 나면 그냥 익스텐션이 터져버린다. 예외 처리 깔끔하게 해놔야겠다.
그리고 테스트코드 작성해야겠다. playwright
로 테스트코드를 작성할거다. 공식 문서에도 크롬 익스텐션에서 사용하는 예제가 있어서 E2E 테스트 툴로 사용하면 될 것 같다.
내일 할 일
- 알고리즘 문제 풀이
- 블로그 정리
- 포트폴리오 정리
- 프로그라피 플젝 시작?? 내일 디자인 나오면 바로 회의
zustand
공식문서 읽기 <- 플젝 적용해야해서 읽어야함